package com.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;


/**
 * <p>Title: 字符串操作工具类</p>
 * <p>Description: </p>
 * @author	
 * @version	
*/
public class StringUtil {

	public final static String FORMAT_DATE = "yyyy-MM-dd";
	public final static String FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";
	
	
	/**
	 * 生成UUID
	 * @return
	 * @return String
	 * @Author: TDW
	 * @Date: 2015年4月20日 下午1:47:46
	 * @ModifyUser：TDW
	 * @ModifyDate: 2015年4月20日 下午1:47:46
	 */
	public static String createUUID(){
		return UUID.randomUUID().toString();
	}
	
	/**
	 * 随机生成len位字符串，由字母、数字组成
	 * @param len
	 * @return
	 * @return String
	 * @Author: TDW
	 * @Date: 2015年4月20日 下午1:48:04
	 * @ModifyUser：TDW
	 * @ModifyDate: 2015年4月20日 下午1:48:04
	 */
	public static String randomStr(int len) {
		if (len == 0) {
			return "";
		}
		int a = (int) (Math.random() * 3);
		if (a == 0) {
			return ((int) (Math.random() * 10)) + randomStr(len - 1);
		} else if (a == 1) {
			return ((char) ((int) (Math.random() * 26) + 65))
					+ randomStr(len - 1);
		} else {
			return ((char) ((int) (Math.random() * 26) + 97))
					+ randomStr(len - 1);
		}
	}
	
	
	
	/** 
	 * 判断数组strs中是否有str这个值
	 * 
	 * @param strs
	 * @param str
	 * @return 有true 没有false
	 */
	public static boolean hasInArray(String[] strs, String str) {
		for (String tmp : strs) {
			if (tmp.equals(str)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 逐个判断数组names中的每个字符串是否为空
	 * 
	 * @param names
	 * @return 有一个为空true 都不为空 false
	 */
	public static boolean isEmpty(String[] names) {
		if(names == null) return true;
		for (String name : names) {
			if (StringUtils.isEmpty(name)) {
				return true;
			} else {
				continue;
			}
		}
		return false;
	}
	
	/**
	 * 去除字符串数组中为空的选项
	 * 
	 * @param names
	 * @return 
	 */
	public static Object[] clearEmpty(Object[] names) {
		List<Object> nameList = new ArrayList<Object>();
		for (Object name : names) {
			if (!StringUtils.isEmpty(name.toString())) {
				nameList.add(name);
			}
		}
		return nameList.toArray();
	}

	/**
	 * 逐个判断数组names中的每个字符串是否为空
	 * 
	 * @param names
	 * @return 有一个为空true 都不为空 false
	 */
	public static boolean isEmpty(Object[] names) {
		for (Object name : names) {
			if (StringUtils.isEmpty(name.toString())) {
				return true;
			} else {
				continue;
			}
		}
		return false;
	}
	
	/**
	 * 判断字符串是否为空
	 * 
	 * @param names
	 * @return 不为空返回true 为空 false
	 */
	public static boolean isEmpty(String name) {
//			if (StringUtils.isEmpty(name)) {
//				return true;
//			} 
//		return false;
		return StringUtils.isEmpty(name);
	}
	
	/**
	 * @Methodname: isNotEmpty
	 * @Discription: TODO
	 * @param name
	 * @return
	 *
	 */
	public static boolean isNotEmpty(String name){
		return StringUtils.isNotEmpty(name);
	}


	/**
	 * 如果字符串为null或者空串返回空""
	 * 	否则直接返回
	 * @param srcValue
	 * @return 处理后的值
	 */
	public static String getValue(String srcValue) {
		if (srcValue == null || srcValue.toString().equals(""))
			return "";
		return srcValue;
	}
	
	public static int getIntValue(String srcValue) {
		if (srcValue == null || srcValue.toString().equals(""))
			return 0;
		return Integer.parseInt(srcValue);
	}

	public static int getIntValue(HttpServletRequest request, String srcValue) {
		return getIntValue(request.getParameter(srcValue));
	}
	
	public static long getLongValue(String srcValue) {
		if (srcValue == null || srcValue.toString().equals(""))
			return 0;
		return Integer.parseInt(srcValue);
	}

	public static long getLongValue(HttpServletRequest request, String srcValue) {
		return getLongValue(request.getParameter(srcValue));
	}
	
	public static double getDoubleValue(String srcValue) {
		if (srcValue == null || srcValue.toString().equals(""))
			return 0;
		return Double.parseDouble(srcValue);
	}

	public static double getDoubleValue(HttpServletRequest request, String srcValue) {
		return getDoubleValue(request.getParameter(srcValue));
	}
	
	/**
	 * 获得前台请求参数
	 * @param request
	 * @param requestKey
	 * @return srcValue参数对应的值
	 */
	public static String getValue(HttpServletRequest request, String requestKey) {
		String decode = null;
		try {
			String sourceValue = getValue(request.getParameter(requestKey));
			decode = URLDecoder.decode(sourceValue, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return decode;
	}
	
	/**
	 * 根据参数编码所对应的数据值
	 * @param value
	 * @return String
	 */
	public static String encodeValue(String value) {
		try {
			value = URLEncoder.encode(value, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * 根据参数解码所对应的数据值
	 * @param value
	 * @return String
	 */
	public static String decodeValue(String value) {
		try {
			value = URLDecoder.decode(new String(value.getBytes("iso-8859-1"),"UTF-8"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * 获得字符串数组的值
	 * 	以逗号分隔
	 * @param srcArray
	 * @return 以逗号分隔的值
	 */
	public static String getValue(String[] srcArray) {
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < srcArray.length; i++) {
			result.append(srcArray[i] + ",");
		}
		return deleteComma(result.toString());
	}

	/**
	 * @dateValue 日期对象，可以是java.util.Date和java.sql.Date
	 * @dateType 格式化的类型,date和datetime
	 */
	public static String getValue(Object dateValue, String dateType) {
		if (dateValue == null)
			return "";
		if (dateValue instanceof java.sql.Date) {
			return dateValue.toString();
		} else if (dateValue instanceof java.util.Date) {
			if (dateType.equals("date")) {
				java.text.SimpleDateFormat sfdate = new java.text.SimpleDateFormat(FORMAT_DATE);
				return sfdate.format(dateValue);
			} else if (dateType.equals("datetime")) {
				java.text.SimpleDateFormat sftime = new java.text.SimpleDateFormat(FORMAT_DATETIME);
				return sftime.format(dateValue);
			} else {
				return "date type not exists!";
			}
		} else {
			return "is not date !";
		}
	}
	
	/**
	 * 用字符串获得日期
	 * @throws ParseException 
	 * @dateValue 日期字符串
	 * @dateType 格式化的类型,date和datetime
	 */
	public static Date getDate(String dateValue, String dateType) throws ParseException {
		if (dateValue == null)
			return null;
		if (dateType.equals("date")) {
			SimpleDateFormat sfdate = new SimpleDateFormat(FORMAT_DATE);
			return sfdate.parse(dateValue);
		} else if (dateType.equals("datetime")) {
			SimpleDateFormat sftime = new SimpleDateFormat(FORMAT_DATETIME);
			return sftime.parse(dateValue);
		}
		return null;
	}
	
	/**
	 * 用字符串获得java.sql.Date日期
	 * @throws ParseException 
	 * @dateValue 日期字符串
	 * @dateType 格式化的类型,date和datetime
	 */
	public static java.sql.Date getSqlDate(String dateValue, String dateType) throws ParseException {
		Date date = getDate(dateValue, dateType);
		if(date == null) {
			return null;
		}
		return new java.sql.Date(date.getTime());
	}

	/**
	 * 删除字符串最后的逗号
	 * @param src
	 * @return
	 */
	public static String deleteComma(String src) {
		src = getValue(src);
		if (!src.endsWith(",")) {
			return src;
		}
		src = src.substring(0, src.length() - 1);
		return src;
	}
	
	/**
	 * @Methodname: getMapValueToStr
	 * @Discription: 通过key值Map获取value
	 * @param map
	 * @param key
	 * @return
	 *
	 */
	public static String getMapValueToStr(Map map, String key)
	{
		return map.get(key) != null ? map.get(key).toString() : "";
	}
	
	public static String replaceTabs(String str) {
		return str.replaceAll("\\\\t", "").replaceAll("\\\\r", "").replaceAll("\\\\n", "");
	}
	
//	/**
//	 * 
//	 * @Methodname: checkMessyCode
//	 * @Discription: 取字符串（如果是乱码，直接转换）
//	 * @param s
//	 * @return
//	 *
//	 */
//	public static String getStringForMessyCode(String s) {
//		if(isEmpty(s))
//			return s;
//		try {
//			if(MessyCodeUtil.isMessyCode(s)) {
//				return new String(s.getBytes("ISO-8859-1"),"utf-8");
//			}else {
//				return s;
//			}
//		} catch (UnsupportedEncodingException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//			throw new BusinessException(e.getMessage());
//		}
//	}
	
	// 根据Unicode编码完美的判断中文汉字和符号 
	public static boolean isChinese(char c) { 
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); 
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS 
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B 
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS 
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) { 
            return true; 
        } 
        return false; 
    } 

    // 完整的判断中文汉字和符号 
    public static boolean isChinese(String strName) { 
        char[] ch = strName.toCharArray(); 
        for (int i = 0; i < ch.length; i++) { 
            char c = ch[i]; 
            if (isChinese(c)) { 
                return true; 
            } 
        } 
        return false; 
    } 
    
    
    public static String getRondom(int length){
		Random random = new Random();
		String result="";
		for(int i=0;i<length;i++){
			result+=random.nextInt(10);
		}
		return result;
	}
    
    

	/**
	 * 计算两个字符串的相似度
	 * @param str
	 * @param target
	 * @return
	 * @author
	 */
	private static int compare(String str, String target) {
        int d[][]; // 矩阵
        int n = str.length();
        int m = target.length();
        int i; // 遍历str的
        int j; // 遍历target的
        char ch1; // str的
        char ch2; // target的
        int temp; // 记录相同字符,在某个矩阵位置值的增量,不是0就是1
        if (n == 0) {
            return m;
        }
        if (m == 0) {
            return n;
        }
        d = new int[n + 1][m + 1];
        for (i = 0; i <= n; i++) { // 初始化第一列
            d[i][0] = i;
        }
        for (j = 0; j <= m; j++) { // 初始化第一行
            d[0][j] = j;
        }
        for (i = 1; i <= n; i++) { // 遍历str
            ch1 = str.charAt(i - 1);
            // 去匹配target
            for (j = 1; j <= m; j++) {
                ch2 = target.charAt(j - 1);
                if (ch1 == ch2) {
                    temp = 0;
                } else {
                    temp = 1;
                }
                // 左边+1,上边+1, 左上角+temp取最小
                d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + temp);
            }
        }
        return d[n][m];
    }
    
    private static int min(int one, int two, int three) {
        return (one = one < two ? one : two) < three ? one : three;
    }
    
    /**
     * 获取两字符串的相似度
     * 
     * @param str
     * @param target
     * 
     * @return
     */
    public static double getSimilarityDegree(String str, String target) {
        return 1 - (float) compare(str, target) / Math.max(str.length(), target.length());
        
    }
    
    
    
    public static void main(String[] args) {
    	System.out.println("is chinese "+StringUtil.isChinese('中'));
    	System.out.println("is chinese "+StringUtil.isChinese('a'));
		System.out.println("is chinese "+StringUtil.isChinese("中国"));
		System.out.println("is chinese "+StringUtil.isChinese("中国a"));
		System.out.println(randomStr(10));
		
		
		System.out.println(getSimilarityDegree("鱼香肉丝","鱼香肉丝"));
        System.out.println(getSimilarityDegree("a鱼香肉丝","鱼香肉丝"));
        System.out.println(getSimilarityDegree("鱼香肉丝","鱼香肉丝a"));
        System.out.println(getSimilarityDegree("鱼香肉丝","鱼香f肉丝a"));
        System.out.println(getSimilarityDegree("s鱼香肉丝","鱼香f肉丝a"));
        System.out.println(getSimilarityDegree("鱼香肉丝","鱼香f肉丝a"));
	}

	public static String randIP() {
		// TODO Auto-generated method stub
		return null;
	}
}
